import { h, ref } from "vue";
import type { VNode, Component } from "vue";
import { ElDialog, ElButton, type DialogProps } from "element-plus";
import type { ExtractProps } from "../types";
import { ComponentHelper } from "../Helper/ComponentHelper";

export const openDialog = <C extends Component>(
  type: C | VNode,
  props?: Omit<ExtractProps<C>, "ref"> & {
    /** 插槽 */
    slots?: Record<string, unknown> | (() => VNode[] | VNode);
  },
  dialogProps?: Partial<DialogProps> & {
    onConfirm?: (done: (loading?: boolean) => void) => void;
    showCancelButton?: boolean;
    showConfirmButton?: boolean;
    showRestFormButton?: boolean;
    confirmButtonText?: string;
    cancelButtonText?: string;
  },
  extraButton?: (comRef: { value: any }) => VNode[] | VNode
) => {
  // 创建响应式开关，控制对话框显示与隐藏
  const open = ref(true);
  // 创建响应式加载状态，用于确定按钮的 loading 效果
  const _loading = ref(false);
  // 超时为完成时钟
  let timeout: number;
  // 解构 组件的属性
  const { slots, ..._props } = props ?? {};
  // 解构 dialogProps，分离出自定义属性并保留其他 Dialog 属性
  const {
    showConfirmButton = true,
    confirmButtonText = "确定",
    showCancelButton = true,
    cancelButtonText = "取消",
    onConfirm,
    showRestFormButton,
    ..._dialogProps
  } = dialogProps || {};
  // 创建组件实例的引用，用于后续调用其方法（如 validate、resetFields）
  const comRef = ref();
  // 定义渲染函数，返回一个 ElDialog 的 VNode

  const dialog = () =>
    h(
      ElDialog,
      {
        closeOnClickModal: false, //禁止点击模态框关闭对话框
        showClose: false, // 不显示关闭按钮
        alignCenter: true, // 垂直居中显示
        ..._dialogProps, // 展开传入的 Dialog 属性
        modelValue: open.value, // 绑定显示状态
        onClosed() {
          // 对话框完全关闭后，卸载应用并移除 DOM 元素，防止内存泄漏
          Dialog.unmount();
        },
      },
      {
        // 默认插槽：渲染传入的组件，并传递 props 和 ref
        default: () => h(type, { ..._props, ref: comRef }, slots),
        // 底部插槽：包含额外按钮、取消、确定按钮
        footer: () => {
          const controlbtn: VNode[] = [];
          // 取消按钮：点击后关闭对话框
          if (showCancelButton) {
            controlbtn.push(
              h(
                ElButton,
                { onClick: () => (open.value = false) },
                () => cancelButtonText
              )
            );
          }
          // 确定按钮：带 loading 状态，点击后先校验再执行确认逻辑
          if (showConfirmButton) {
            controlbtn.push(
              h(
                ElButton,
                {
                  type: "primary", // 主要按钮样式
                  loading: _loading.value, // 绑定 loading 状态
                  onClick: async () => {
                    // 尝试调用组件内部的 validate 方法进行表单验证
                    const valid = await comRef?.value?.validate?.();
                    // 如果验证存在且失败，则中断提交
                    if (valid !== undefined && !valid) return;
                    // 如果没有提供 onConfirm 回调，则直接关闭
                    if (!onConfirm) {
                      open.value = false;
                    } else {
                      // 否则开启 loading，并执行用户定义的确认逻辑
                      timeout = window.setTimeout(() => {
                        _loading.value = true;
                      }, 100);
                      onConfirm(done);
                    }
                  },
                },
                () => confirmButtonText
              )
            );
          }
          const controlBox = h(
            "div",
            { style: { marginLeft: "auto" } },
            controlbtn
          );
          const child = [...getExtraButton(), controlBox];
          return h("div", { style: { display: "flex" } }, child);
        },
      }
    );

  // 生成底部额外按钮（包括可选的重置按钮和用户自定义按钮）
  const getExtraButton = () => {
    // 如果 showRestFormButton 为 true，则添加重置按钮
    const restBtn = showRestFormButton
      ? [
          h(
            ElButton,
            { onClick: () => comRef.value?.resetFields?.() }, // 调用组件的 resetFields 方法
            () => "重置"
          ),
        ]
      : [];
    // 如果没有额外按钮函数，则只返回重置按钮（如果有的话）
    if (!extraButton) return restBtn;
    // 执行 extraButton 函数，获取自定义按钮 VNode
    const buttons = extraButton(comRef);
    // 确保按钮是一个数组
    const extraBtns = Array.isArray(buttons) ? buttons : [buttons];
    // 合并重置按钮和额外按钮，并过滤掉 null/undefined
    return [...restBtn, ...extraBtns.filter((btn) => btn != null)];
  };

  // 确认操作完成后的回调函数，用于关闭对话框或停止 loading
  const done = (loading: boolean = true) => {
    // 清除定时器
    clearTimeout(timeout);
    // 停止 loading 状态
    _loading.value = false;
    // 如果 loading 为 false，则直接返回
    if (!loading) return;
    // 默认关闭 loading 并关闭对话框
    open.value = false;
  };
  // 挂载函数
  const Dialog = ComponentHelper.mount(dialog);
};
